package com.ciaojian.worker.service;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ciaojian.core.enums.business.CheckUserClockTypeEnum;
import com.ciaojian.core.enums.business.LeaveDetailType;
import com.ciaojian.core.enums.business.WorkerApplyStatusEnum;
import com.ciaojian.core.enums.business.WorkerApplyTypeEnum;
import com.ciaojian.core.mapper.WorkerApplyMapper;
import com.ciaojian.core.model.LeaveDetail;
import com.ciaojian.core.model.ReplaceDetail;
import com.ciaojian.core.model.Scheduling;
import com.ciaojian.core.model.WorkerApply;
import com.ciaojian.core.model.dto.WorkerApplyDTO;
import com.ciaojian.core.model.vo.CheckUser;
import com.ciaojian.core.service.WorkerApplyService;
import com.ciaojian.core.util.StringUtil;
import com.ciaojian.worker.model.param.LeaveApplyParam;
import com.ciaojian.worker.model.param.ReplaceApplyParam;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author Atlakyn
 */
@Service
public class WorkerApplyServiceImpl extends WorkerApplyService<WorkerApplyMapper, WorkerApply> {
    @Resource
    private SchedulingServiceImpl schedulingService;

    public Page<Map<String, Object>> listByWorker(WorkerApplyDTO params,
                                                  Page<Map<String, Object>> page) {
        return this.baseMapper.listContainLeaveDetail(page, params);
    }

    /**
     * 计算请假时长
     *
     * @param param 参数
     * @return 请假时长(天)
     */
    public Double calculateDays(LeaveApplyParam param) {
        List<Scheduling> schedulingList = schedulingService.listBetweenDate(param.getWorkerId(), param.getBeginDate(), param.getEndDate());
        Assert.notEmpty(schedulingList, "选中的时间没有排班,请重新选择");

        //        // 如果是从下午开始则天数 -0.5
//        days = param.getBeginRange().compareTo(1) == 0 ? days - 0.5 : days;
//        // 如果是从上午结束则天数 -0.5
//        days = param.getEndRange().compareTo(0) == 0 ? days - 0.5 : days;

        return (double) schedulingList.size();
    }


    /**
     * 请假申请
     *
     * @param param 参数
     * @return 成功返回 true
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean leaveApply(LeaveApplyParam param) {
        // 判断申请的时间段内是否有排班
        List<Scheduling> schedulingList = schedulingService.listBetweenDate(param.getWorkerId(), param.getBeginDate(), param.getEndDate());
        Assert.notEmpty(schedulingList, "选中的时间没有排班,请重新选择");

        // 申请
        WorkerApply workerApply = new WorkerApply();
        workerApply.setApplyDate(new Date());
        workerApply.setWorkerId(param.getWorkerId());
        workerApply.setWorkerName(param.getWorkerName());
        workerApply.setTitle(param.getWorkerName().concat(" 提交了").concat(LeaveDetailType.PERSONAL_LEAVE.getDescription()));
        workerApply.setStoreId(param.getStoreId());
        workerApply.setStoreName(param.getStoreName());
        workerApply.setType(WorkerApplyTypeEnum.LEAVE);
        workerApply.insert();

        // 添加头表成功后添加子表
        LeaveDetail leaveDetail = new LeaveDetail();
        leaveDetail.setApplyId(workerApply.getId());
        leaveDetail.setBeginDate(param.getBeginDate());
        leaveDetail.setBeginRange(param.getBeginRange());
        leaveDetail.setEndDate(param.getEndDate());
        leaveDetail.setEndRange(param.getEndRange());
        leaveDetail.setReason(param.getReason());
        leaveDetail.setType(param.getType());
        leaveDetail.setImg(param.getImg());

        // 请假天数
        double days = schedulingList.size();
        // 请假半天
        if(ObjectUtil.isNotNull(param.getHalf())) {
            days= 0.5;
            leaveDetail.setHalf(param.getHalf());
        }

//        // 如果是从下午开始则天数 -0.5
//        days = param.getBeginRange().compareTo(1) == 0 ? days - 0.5 : days;
//        // 如果是从上午结束则天数 -0.5
//        days = param.getEndRange().compareTo(0) == 0 ? days - 0.5 : days;
        leaveDetail.setDays(days);
        return leaveDetail.insert();
    }

    /**
     * 补卡申请
     *
     * @param param 参数
     * @return 成功返回 true
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean replaceApply(ReplaceApplyParam param) {
        // 先添加头部表
        WorkerApply workerApply = new WorkerApply();
        workerApply.setApplyDate(new Date());
        workerApply.setWorkerId(param.getWorkerId());
        workerApply.setWorkerName(param.getWorkerName());
        workerApply.setTitle(param.getWorkerName().concat(" 提交了补卡"));
        workerApply.setStoreId(param.getStoreId());
        workerApply.setStoreName(param.getStoreName());
        workerApply.setType(WorkerApplyTypeEnum.REPLACE);
        // 添加头表成功后添加子表
        workerApply.insert();
        ReplaceDetail replaceDetail = new ReplaceDetail()
                .setApplyId(workerApply.getId())
                .setReplaceDate(param.getReplaceDate())
                .setReason(param.getReason())
                .setType(param.getType());
        replaceDetail.insert();
        // 新增打卡记录
        CheckUser checkUser = new CheckUser();
        String punchIn = "上班打卡";
        String punchOut = "下班打卡";
        // 上班卡
        if (punchIn.equals(param.getType())) {
            checkUser.setDate(new SimpleDateFormat("yyyy-MM-dd").format(param.getReplaceDate()))
                    .setTime("00:00:00")
                    .setType("上班打卡")
                    .setUserId(param.getWorkerId())
                    .setClockType(CheckUserClockTypeEnum.PUNCH_IN_REPLACE);
        } else if (punchOut.equals(param.getType())) {
            checkUser.setDate(new SimpleDateFormat("yyyy-MM-dd").format(param.getReplaceDate()))
                    .setTime("23:59:59")
                    .setType("下班班打卡")
                    .setUserId(param.getWorkerId())
                    .setClockType(CheckUserClockTypeEnum.PUNCH_OUT_REPLACE);
        }
        return checkUser.insert();
    }

    /**
     * 撤销申请
     *
     * @param workerApply 申请记录
     * @return 撤销结果
     */
    public Boolean withdraw(WorkerApply workerApply) {
        workerApply.setStatus(WorkerApplyStatusEnum.WITHDRAW);
        return workerApply.updateById();
    }
}
